package ru.bytedog.oiot.counter.bot.service.dashboard;

import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import ru.bytedog.oiot.counter.bot.bean.AppAuthority;
import ru.bytedog.oiot.counter.bot.bean.BotAnswer;
import ru.bytedog.oiot.counter.bot.bean.ErrorCode;
import ru.bytedog.oiot.counter.bot.dto.dashboard.LoginData;
import ru.bytedog.oiot.counter.bot.entity.BotUser;
import ru.bytedog.oiot.counter.bot.exception.ServiceException;
import ru.bytedog.oiot.counter.bot.service.TelegramBot;
import ru.bytedog.oiot.counter.bot.service.UserService;

@Service
@Slf4j
public class AuthService {
    private final TelegramBot bot;
    private final UserService userService;
    private final UserOtpService otpService;
    private final AuthenticationManager authenticationManager;

    public AuthService(TelegramBot bot, UserService userService, UserOtpService otpService, AuthenticationManager authenticationManager) {
        this.bot = bot;
        this.userService = userService;
        this.otpService = otpService;
        this.authenticationManager = authenticationManager;
    }

    public void sendOtpForUser(String username) throws ServiceException {
        log.debug("Запрос на отправку OTP для пользователя: {}", username);
        try {
            BotUser user = userService.getByUsername(username);
            if (!isAvailableAuth(user)) {
                throw new ServiceException(ErrorCode.FORBIDDEN);
            }
            String authCode = otpService.createOtp(user);
            bot.sendMessage(new BotAnswer("Ваш код для входа: " + authCode, user.getChatId()));
        } catch (Exception e) {
            log.error("Ошибка при формировании и отправке OTP кода", e);
            if (e instanceof ServiceException) {
                throw e;
            }
            throw new ServiceException(ErrorCode.SERVICE_ERROR);
        }
    }

    public void login(LoginData loginData) throws ServiceException {
        try {
            Authentication authentication = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(
                    loginData.getUsername(), loginData.getPassword()));
            SecurityContextHolder.getContext().setAuthentication(authentication);
        } catch (AuthenticationException e) {
            throw new ServiceException(ErrorCode.OTP_CODE_ERROR);
        }
    }

    private boolean isAvailableAuth(BotUser user) {
        log.debug("Проверка пользователя {} на возможность входа в панель администратора", user.getUsername());
        boolean isEnabled = AppAuthority.ADMIN.getRole().equals(user.getRole());
        log.debug("Вход для пользователя {}: {}", user.getUsername(), isEnabled ? "разрешен" : "запрещен");
        return isEnabled;
    }

}
